﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.Objects.DataClasses;
using Newtonsoft.Json;
using System.Collections;

namespace Common.Serializable
{
    public class JsonSerializable
    {
        public static string Serialize(object obj)
        {
            //resetUnLoadedRef(obj);
            using (StringWriter sw = new StringWriter(System.Globalization.CultureInfo.InvariantCulture))
            {
                JsonSerializer serializer = new JsonSerializer
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    //TypeNameHandling = TypeNameHandling.Auto,
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects,                     
                    ContractResolver = new EFContractResolver()
                };
                using (JsonWriter jw = new JsonTextWriter(sw))
                {
                    jw.Formatting = Formatting.Indented;
                    serializer.Serialize(jw, obj);
                }
                return sw.ToString();
            }
        }

        public static T Deserialize<T>(string json)
        {
            using (StringReader sw = new StringReader(json))
            {
                JsonSerializer serializer = new JsonSerializer
                {
                    MissingMemberHandling = MissingMemberHandling.Ignore,
                    ContractResolver = new EFContractResolver()
                    //TypeNameHandling = TypeNameHandling.Objects
                };
                using (JsonReader jw = new JsonTextReader(sw))
                {
                    return serializer.Deserialize<T>(jw);
                }

            }

        }

        protected static void resetUnLoadedRef(object obj)
        {
            IEntityWithRelationships entity = obj as IEntityWithRelationships;
            if (entity != null)
            {
                var list=entity.RelationshipManager.GetAllRelatedEnds().ToList();
                foreach (var i in list)
                {
                    if (i.IsLoaded)
                    {
                        if (i is IEnumerable)
                        {
                            foreach (var j in (IEnumerable)i)
                            {
                                resetUnLoadedRef(j);
                            }
                        }
                        else
                        {
                            resetUnLoadedRef(i);
                        }
                    }
                    else
                    {
                        dynamic d = i;
                        if (i is IEnumerable)
                        {
                            d = null; 
                        }
                        else
                        {
                            d.Value = null;
                        }
                    }
                }

            }
        }
    }
}
